/*-----------------------------------------------------------------------------
	The contents of this file are subject to the Mozilla Public License
	Version 1.1 (the "License"); you may not use this file except in
	compliance with the License. You may obtain a copy of the License at
	http://www.mozilla.org/MPL/
	
	Software distributed under the License is distributed on an "AS IS"
	basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
	License for the specific language governing rights and limitations
	under the License.
	
	The Original Code is Fever Framework code.
	
	The Initial Developer of the Original Code is Romain Ecarnot.
	Portions created by Initial Developer are Copyright (C) 2006
	the Initial Developer. All Rights Reserved.
	
	Contributor(s):
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
-----------------------------------------------------------------------------*/

import org.aswing.ASWingUtils;
import org.aswing.BorderLayout;
import org.aswing.Component;
import org.aswing.Container;
import org.aswing.CursorManager;
import org.aswing.JPanel;
import org.aswing.MCPanel;
import org.aswing.RepaintManager;

import com.bourre.events.BasicEvent;
import com.bourre.events.EventType;
import com.bourre.structures.Rectangle;

import fever.app.accelerator.ShortcutMap;
import fever.events.ApplicationEvent;
import fever.events.FeverController;
import fever.events.FeverEventList;
import fever.events.KeyboardEvent;
import fever.Fever;
import fever.log.FeverDebug;
import fever.utils.Stringifier;

import fvaswing.commands.FvApplyLookAndFeel;
import fvaswing.commands.FvLockBusySystem;
import fvaswing.commands.FvOpenLocalisationChooser;
import fvaswing.commands.FvOpenThemeChooser;
import fvaswing.events.FvAsWingEventList;
import fvaswing.utils.FvComponentBuffer;

/**
 * Main class for AsWing application.
 * 
 * <p>Defines a default container for application UI.<br />
 * 
 * <p>Sets <strong>ASWingUtils.setRootMovieClip</strong> to 
 * {@link fever.display.FeverStage#root} )
 * 
 * <p>Sets <strong>CursorManager.CURSOR_LAYER</strong> to  
 * {@link fever.display.FeverStage#createCursorTarget()}
 * 
 * <p>Preloads all components register in 
 * {@link fvaswing.utils.FvComponentBuffer}
 * 
 * @see fever.display.FeverStage
 */
class fvaswing.FvAsWing
{
	//-------------------------------------------------------------------------
	// Constants definition
	//-------------------------------------------------------------------------
	
	/** Read only. Main movieclip level for AsWing UI creation. */
	public static function get ASWING_LEVEL() : String { return '__aswl__'; }
	
	
	//-------------------------------------------------------------------------
	// Events definition
	//-------------------------------------------------------------------------
	
	/** 
	 * Event type broadcasted when main container ( and children ) has 
	 * been painted.
	 * 
	 * <p>Add event listener to {@link fever.display.FeverStage#addEventListener} 
	 * to listen to this event.<br />
	 * {@code
	 *   Fever.stage.addEventListener( FvAsWing.onUICompleteEVENT, this );
	 * }
	 * 
	 * <p>Most case event is dispatched only once ( at the application 
	 * initialization ) but if you force the UI repainting, event is broadcasted 
	 * again.
	 */
	public static var onUICompleteEVENT : EventType = new EventType( 'onUIComplete' );
	
	
	//-------------------------------------------------------------------------
	// Private properties
	//-------------------------------------------------------------------------
	
	private static var _instance : FvAsWing;
	
	private var _mc : MCPanel;
	private var _container : JPanel;
	private var _oldSize : Rectangle;
	
	
	//-------------------------------------------------------------------------
	// Public Properties
	//-------------------------------------------------------------------------
	
	/**
	 * Type identifier for shortcut definition for AsWing component.
	 * 
	 * <p>Take a look at {@link fever.app.accelerator.ShortcutMap} class and 
	 * {@link fever.app.accelerator.ShortcutMap#registerCustomObject()} method.
	 */
	public static var AWSHORTCUT : String = 'AwComponentSC';
	
	
	//-------------------------------------------------------------------------
	// Public API
	//-------------------------------------------------------------------------
	
	/**
	 * Only inits {@link FvAsWing} engine.
	 */
	public static function init() : Void
	{
		getInstance();	
	}
	
	/**
	 * Returns {@link fvaswing.FvAsWing} instance.
	 * 
	 * <p>Always returns the same instance.<br />
	 * Design Pattern Singleton.
	 * @return {@link fvaswing.FvAsWing} instance
	 */
	public static function getInstance() : FvAsWing
	{
		if( !_instance ) _instance = new FvAsWing();
		return _instance;	
	}
	
	/**
	 * Inits Fever AsWing Stage system and returns the new 
	 * {@code ASWingUtils.getRootMovieClip()} target.
	 */
	public function getRootMovieClip() : MovieClip
	{
		return ASWingUtils.getRootMovieClip();	
	}
	
	/**
	 * Returns main application container.
	 */
	public function getContainer() : Container
	{
		return _container;	
	}
	
	/**
	 * Returns string representation.
	 */
	public function toString() : String
	{
		return Stringifier.parse( this );
	}
	
	
	//-------------------------------------------------------------------------
	// Private implementation
	//-------------------------------------------------------------------------
	
	/**
	 * Constructor.
	 */
	private function FvAsWing()
	{
		_initUI();
		_initController();
		_initShorcutMapping();
	}
	
	private function _initUI() : Void
	{
		ASWingUtils.setRootMovieClip( Fever.stage.root );
		CursorManager.CURSOR_LAYER = Fever.stage.createCursorTarget();
		
		_container = new JPanel();
		_container.setLayout( new BorderLayout( 5, 5 ) );
		
		var size : Rectangle = Fever.application.getSize();
		
		if( !size ) size = new Rectangle( 800, 600, 0, 0 );
		
		_mc = new MCPanel( 
			Fever.stage.createEmptyMovieClip( FvAsWing.ASWING_LEVEL ),
			size.width, 
			size.height 
		);
		_mc.setLayout( new BorderLayout() );
		_mc.append( _container, BorderLayout.CENTER );
		
		RepaintManager.getInstance().addCallAfterNextPaintTime( _onInterfaceReady );
		
		FvComponentBuffer.preload();
		
		Fever.application.addEventListener( ApplicationEvent.onResizeEVENT, this );
	}
	
	private function _initController() : Void
	{
		var o : FeverController = FeverController.getInstance();
		
		o.push( FvAsWingEventList.onLocalisationChooserEVENT, new FvOpenLocalisationChooser() );
		o.push( FvAsWingEventList.onThemeChooserEVENT, new FvOpenThemeChooser() );
		o.push( FeverEventList.onLockInteractionEVENT, new FvLockBusySystem() );		o.push( FeverEventList.onApplyLookAndFeelEVENT, new FvApplyLookAndFeel() );
	}
	
	private function _initShorcutMapping() : Void
	{
		ShortcutMap.addType( AWSHORTCUT, this, _onShortcutActivated );
	}
	
	private function onApplicationResize( event : ApplicationEvent ) : Void
	{
		var size : Rectangle = Fever.application.getSize();
		
		if( _oldSize.width != size.width || _oldSize.height != size.height )
		{
			if( size.width && size.height )
			{
				_mc.setSize( size.width, size.height );
				_mc.revalidateIfNecessary();
				
				_oldSize = size;
			}
		}
	}
	
	private function _onInterfaceReady() : Void
	{
		FeverDebug.INFO( 'User Interface complete' );
		
		Fever.stage.broadcastEvent( new BasicEvent( onUICompleteEVENT ) );
	}
	
	private function _onShortcutActivated( c : Component, event : KeyboardEvent ) : Void
	{
		c.fireActionEvent();
	}
}